import {LoggerFactory} from "../logs/Logger";
import {HttpServer} from "./HttpServer";
import {env} from "../config/ApplicationContext";
import {Application} from "express-serve-static-core";

const log = LoggerFactory.getLogger('ServerContext')

export class ServerContext {
    private _server: HttpServer | undefined
    private _plugins: Array<(server: Application) => void> = []
    private _environment: { [key: string]: any } = {}


    get environment(): {} {
        return this._environment;
    }

    set environment(value: {}) {
        this._environment = value;
    }

    get server(): HttpServer | undefined {
        return this._server;
    }

    set server(value: HttpServer) {
        this._server = value;
    }

    get plugins(): Array<(server: Application) => void> {
        return this._plugins;
    }

    public addPlugin(action: (server: Application) => void): ServerContext {
        this.plugins.push(action)
        return this;
    }

    public async start() {
        return new Promise<ServerContext>(async (resolve, reject) => {
            try {
                const conf = await env.loadConfig()
                this._environment = conf;
                let host = '127.0.0.1'
                let port = 3223
                const keys = Object.keys(conf);
                if (keys.includes('host')) {
                    host = conf['host']
                }
                if (keys.includes('port')) {
                    port = conf['port']
                }

                // 创建http服务实例
                this.server = new HttpServer(port, host);
                for (let plugin of this.plugins) {
                    plugin.call(plugin, this.server.server)
                }
                this.server.start(() => {
                    // log.info(`服务启动完成,点击下面地址访问\nhttp://${host}:${port}/`)
                });
                resolve(this);
            } catch (e) {
                reject(e)
            }
        });
    }

    public getEnv(key: string): any {
        if (this.environment === undefined) return null;
        if (!Object.keys(this.environment).includes(key)) {
            return null;
        }
        return (this.environment as { [key: string]: any })[key];
    }
}

export const context = new ServerContext();